# -*- coding = utf-8 -*-
# @Time : 2022/1/12 20:30
# @Author : GHHHHHHHHH
# @File : regionalBlockMethod.py
# @Software : PyCharm

"""
    Regional block method based on eight neighborhood method
"""
from random import shuffle
import cv2 as cv
from tqdm import tqdm
from getColors import initColors


class RegionalBlockMethod(object):
    def __init__(self, background, maxChuck):
        self.background = background
        self.directions = [(1, 1), (1, 0), (0, 1), (-1, -1), (-1, 0), (0, -1), (1, -1), (-1, 1)]
        self._id = maxChuck
        self.colors = initColors(self._id)
        self.xLength = background.shape[0]
        self.yLength = background.shape[1]

    def growth(self, i, j, _id):
        directions = self.directions
        self.background[i][j] = self.colors[_id]
        flag1 = True
        while True:
            flag = True
            if flag1:
                x1, y1 = [i], [j]
            points = []
            for i in range(len(x1)):
                points.append((x1[i], y1[i]))
            if not flag1:
                x1, y1 = [], []
            for i, j in points:
                for direction in directions:
                    try:
                        if tuple(self.background[i + direction[0]][j + direction[1]]) == tuple((255, 255, 255)) \
                                and i + direction[0] != -1 and j + direction[1] != -1:
                            self.background[i + direction[0]][j + direction[1]] = self.colors[_id]
                            x1.append(i + direction[0])
                            y1.append(j + direction[1])
                            flag = False
                    except IndexError:
                        pass
            if flag:
                break
            flag1 = False

    def getChucksEdges(self):
        _id = 0
        for i in tqdm(range(self.xLength)):
            for j in range(self.yLength):
                if tuple(self.background[i][j]) == (255, 255, 255):
                    self.growth(i, j, _id)
                    _id += 1

    def getFullChucks(self):
        colors = self.colors
        for k in tqdm(range(200)):
            newChucks = self.getNeededColoredPoints(self.background)
            for i, chuck in enumerate(newChucks):
                for x, y in chuck:
                    self.background[x][y] = colors[i]

    def getColorId(self, *rgb):
        num = self._id
        numP3 = num // 3 + 1
        temp = 255 // (numP3 + 1)
        if rgb[0] != 0:
            return rgb[0] // temp - 1
        elif rgb[2] != 0:
            return rgb[2] // temp + numP3 - 1
        else:
            return rgb[1] // temp + numP3 * 2 - 1

    def getNeighborPoints(self, x, y):
        directions = self.directions
        shuffle(directions)
        for direction in directions:
            try:
                if tuple(self.background[x + direction[0]][y + direction[1]]) != tuple((0, 0, 0))\
                        and x != 0 and y != 0:
                    return True, self.getColorId(*tuple(self.background[x + direction[0]][y + direction[1]]))
            except IndexError:
                continue
        return False, None

    def getNeededColoredPoints(self, background):
        chucks = [[] for i in range(self._id)]
        for x in range(self.xLength):
            for y in range(self.yLength):
                if tuple(background[x][y]) == (0, 0, 0):
                    flag1, colorId = self.getNeighborPoints(x, y)
                    if flag1:
                        chucks[colorId].append([x, y])
        return chucks

    def mainCircle(self, flag):
        # 第一步，确定有多少个区块
        if flag:
            self.getChucksEdges()
        # 第二步，开始生长~~~
        self.getFullChucks()
        return self.background, self.colors
